var watchlist_DataManager = function(){
    this.STATUS_READY='ready';
    this.STATUS_ERROR='error';
    this.watchListMap = {};
    this.registeredMap = {};
    this.LPLStatus=null;
    this.QSStatus=null;
    this.ScreenerStatus=null;
	this.bDefaultWatchlistLoaded=false;
	this.cacheConstituents=true,
	this.constituentsData={};
	this.LPLTickerValidation=null;
    if(QSPC.checkPermission(0.08)&&QSPC.checkPermission(25)){//have screener and watchlist screener
        this.screenerType='51';
        this.screenerSaved=new QS_SearchDB(this.screenerType);
    }
    this.init();
};
watchlist_DataManager.prototype = {
    init:function(){
       if (typeof(QS_LPLRepId)!="undefined"&&QS_LPLRepId != '') {
	       this.LPLTickerValidation=new tickerValidation('LPL');
	   }else{
	   	   this.LPLStatus=this.STATUS_READY;
	   }
    },
   formatHoldingDate:function(d){
	    var year = d.getFullYear();
	    var month = d.getMonth() + 1;
	    month = month < 10 ? ('0' + month) : month;
	    var day = d.getDate();
	    day = day < 10 ? ('0' + day) : day;
	    return (month + '-' + day + '-' + year);
	},
	checkWatchlistName:function(name){  // false: not exist. Id: exist.
		var t = false; 
		if(name!=""){
			for(var o in this.watchListMap){
				if(this.watchListMap[o].name==name){ // exist
					t = o;
					break;
				}
			}
		}
		return t;
	},
	getWatchlistID:function(name){
		var t = false; 
        if(name!=""){
            for(var o in this.watchListMap){
                if(this.watchListMap[o].name==name){ // exist
                    return o;
                }
            }
        }
		return null;
	},
    _checkDataReady:function(callback){
        if(this.LPLStatus!=null&&this.QSStatus!=null&&(this.ScreenerStatus!=null||!QSPC.checkPermission(0.08))){
            if (typeof(callback) == "function") {
                 callback(this._getPortfolioListFromMap());
            }
        }
    },
    clearScreenerCache:function(id){
        if(this.watchListMap[id]){
            this.watchListMap[id].setReady(false);
        }
    },
    _getScreenerList:function(callback){
        var self=this;
        if(this.ScreenerStatus!=this.STATUS_READY){//everytime need to refresh
            this.screenerSaved.getSearchNameList(function(data){
                var qslang=QS_Lang.watchlist;
                if(data=="error"){
                    self.ScreenerStatus=self.STATUS_ERROR;
                }else{
                    for(var i=0,l=data.length;i<l;i++){
                        if (!self.watchListMap[data[i].id]) {
                            self.watchListMap[data[i].id] = new watchlistData(data[i].id);
                        }
                        self.watchListMap[data[i].id].name = data[i].title;
                        self.watchListMap[data[i].id].type = data[i].type;
                        self.watchListMap[data[i].id].source = 'screener';
                        self.watchListMap[data[i].id].typeTxt =  qslang["dm_screenername"];
                        self.watchListMap[data[i].id].owner = qslang["dm_owner"];
                        self.watchListMap[data[i].id].permission = qslang["dm_readonly"];
                    }
                    self.ScreenerStatus=self.STATUS_READY;
                }
                self._checkDataReady(callback);
            });
        }else{
            self._checkDataReady(callback);
        }
    },
    _getLPLPortfolioList:function(callback){
        var self=this;
        if (self.LPLStatus == 'error'||self.LPLStatus == null){
            self.LPLStatus = null;
            DBHelper.getLPLHouseholdlist(function(data){
                if (data == 'error') {// request error
                    self.LPLStatus = self.STATUS_ERROR;
                }else {
                    if (data != null || data != '' && data != 'false') {
                        var jData = $.evalJSON(data);
                        if (jData && jData.Portfolio) {
                            var houseHoldList = jData.Portfolio,qslang=QS_Lang.watchlist;
                            if (!self.watchListMap[jData.LPLRepId]) {//create my practice
                                self.watchListMap[jData.LPLRepId] = new watchlistData(jData.LPLRepId);
                            }
                            self.watchListMap[jData.LPLRepId].name = qslang["dm_lplname"];
                            self.watchListMap[jData.LPLRepId].type = 0;
                            self.watchListMap[jData.LPLRepId].typeTxt = qslang["dm_lpltype"];
                            self.watchListMap[jData.LPLRepId].source = 'LPLP';
                            self.watchListMap[jData.LPLRepId].owner =  qslang["dm_owner"];
                            self.watchListMap[jData.LPLRepId].permission =  qslang["dm_readonly"];
                            
                            for (var i = 0, l = houseHoldList.length; i < l; i++) {//create householdList
                                if (!self.watchListMap[houseHoldList[i].PfId]) {
                                    self.watchListMap[houseHoldList[i].PfId] = new watchlistData(houseHoldList[i].PfId);
                                }
                                self.watchListMap[houseHoldList[i].PfId].name = houseHoldList[i].Name;
                                self.watchListMap[houseHoldList[i].PfId].updateTime = houseHoldList[i].Date;
                                self.watchListMap[houseHoldList[i].PfId].type = 0;
                                self.watchListMap[houseHoldList[i].PfId].typeTxt =  qslang["dm_plname"];
                                self.watchListMap[houseHoldList[i].PfId].source = 'LPLH';
                                self.watchListMap[houseHoldList[i].PfId].owner = qslang["dm_owner"];
                                self.watchListMap[houseHoldList[i].PfId].permission = qslang["dm_readonly"];
                            }
                        }
                    }
                    self.LPLStatus = self.STATUS_READY; 
                }
                self._checkDataReady(callback);
            });
        }else{
			this._checkDataReady(callback);
		}
    },
    _getQSPortfolioList:function(callback){
        var self=this;
        if (self.QSStatus == 'error'||self.QSStatus == null) {
            self.QSStatus = null;
            DBHelper.getPortfolioList(function(data){
                if (data == 'error') {
                    self.QSStatus = self.STATUS_ERROR;
                }else {
                    if (data != null) {
                        var jData = $.evalJSON(data);
                        if (jData && jData.Portfolios) {
                            var pList = jData.Portfolios,qslang=QS_Lang.watchlist;
                            for (var i = 0, l = pList.length; i < l; i++) {
                                if (!self.watchListMap[pList[i].PfId]) {
                                    self.watchListMap[pList[i].PfId] = new watchlistData(pList[i].PfId);
                                }
                                self.watchListMap[pList[i].PfId].name = pList[i].Name;
                                self.watchListMap[pList[i].PfId].updateTime = pList[i].UpdateTime;
                                self.watchListMap[pList[i].PfId].type = pList[i].Type;
                                self.watchListMap[pList[i].PfId].typeTxt = pList[i].Type == 0 ? qslang["portfolio"] : qslang["type_list"];
								self.watchListMap[pList[i].PfId].permission = self.watchListMap[pList[i].PfId].getPermission()==0?qslang["dm_readonly"]:qslang["dm_write"];
                            }
							DBHelper.saveLocalPortfolioList(data,jData.UpdateTime);
                        }
						
                    }
                    self.QSStatus = self.STATUS_READY;
                }
                self._checkDataReady(callback);
            });
        }else{
			this._checkDataReady(callback);
		}
    },
	getConstituents:function(sid,callback){
		//cacheConstituents,constituentsData
		if(this.cacheConstituents&&this.constituentsData[sid]){
			callback($.extend(true,{},this.constituentsData[sid]));
		}else{
			var self=this;
			DBHelper.getConstituents(sid,function(dataJson){
				if(dataJson.data){
					var sid=dataJson.data.secId,cachData={},pids=dataJson.data.pids;
					if(sid&&pids.length>0){
						cachData={
                            date:dataJson.data.lastDate,
                            pids:pids
                        };
						if(self.cacheConstituents){
							self.constituentsData[sid]=cachData;
						}
						if(callback){callback($.extend(true,{},cachData));}
					}else{
						if(callback){callback(null);}
					}
				}else if(dataJson.ret=="1"){
					if(callback){callback(null);}
				}
			});
		}
	},
    getDefaultPortfolioList:function(callback){
	
		if(this.bDefaultWatchlistLoaded){
			//
			//if the default watchlist has been loaded from server, load it from local cache.
			//
			var result=[];
			for(var pId in this.watchListMap){
				if(this.watchListMap[pId].source=='default'){
					result.push({
						Name:this.watchListMap[pId].name,
						UpdateTime:this.watchListMap[pId].updateTime,
						Type:this.watchListMap[pId].type,
						TypeTxt:this.watchListMap[pId].typeTxt,
						PfId:pId,
						Owner:this.watchListMap[pId].owner,
						Source:this.watchListMap[pId].source,
						Permission:this.watchListMap[pId].permission
					});
				}
			}
			
			callback(result);
			
		}else{
			//
			//if the default watchlist has not been loaded, load it from server.
			//	
			var self=this;
			DBHelper.getDefaultWatchlist(function(data){
			
				if(data&&data!="error"){
					var jData = $.evalJSON(data);
					if(jData&&jData.list){

						for(var i=0;i<jData.list.length;i++){
							var PfId=jData.list[i].watchId,qslang=QS_Lang.watchlist;
							if(!self.watchListMap[PfId]){
								self.watchListMap[PfId]=new watchlistData(PfId);
							}
							self.watchListMap[PfId].name = jData.list[i].watchName;
							self.watchListMap[PfId].owner = qslang["dm_downer"];
							self.watchListMap[PfId].permission = qslang["dm_readonly"];
							self.watchListMap[PfId].source = 'default';  // default watchlist.
							if(jData.list[i].securityType){
								self.watchListMap[PfId].securityType=jData.list[i].securityType;
							}
							if(jData.list[i].groupName){
								self.watchListMap[PfId].group=jData.list[i].groupName;
							}
						}
						self.bDefaultWatchlistLoaded=true;
						//self._checkDataReady(callback);
						callback(self._getPortfolioListFromMap());
					}
				}
	
			});
		}

    },
	subScribeSectorWatchList:function(sectorType,subIndustryId,name,region){
        var pfid = "sector_"+(subIndustryId||name)+"_"+region,qslang=QS_Lang.watchlist;
        if (!this.watchListMap[pfid]) {
            this.watchListMap[pfid] = new watchlistData(pfid);
        }
        this.watchListMap[pfid].industryId = subIndustryId;
        if(region)this.watchListMap[pfid].region = region;
        this.watchListMap[pfid].sectorType = sectorType;
        this.watchListMap[pfid].name = name;
        this.watchListMap[pfid].owner = qslang["dm_downer"];
        this.watchListMap[pfid].permission = qslang["dm_readonly"];
        this.watchListMap[pfid].source = 'sector';  // sector watchlist.
    },
    resetStatus:function(list){
        switch(list){
            case "screener":
                this.ScreenerStatus=null;
                break;
            case "lpl":
                this.LPLStatus=null;
                break;
            case "qs":
                this.QSStatus=null;
                break;
            default:
                break;
        }
    },
    getPortfolioList: function(callback){
        var self = this;
        if (this.ScreenerStatus == self.STATUS_READY&&this.LPLStatus == self.STATUS_READY && this.QSStatus == self.STATUS_READY && this.bDefaultWatchlistLoaded) {
			if (typeof(callback) == "function") {
				callback(this._getPortfolioListFromMap());
			}
		}else {
			this.getDefaultPortfolioList(function(data){
				//callback(data);
				
				//
				//After load default list, starting load other list. This method is to ensure that the default list can be alway display on the topmost in UI. 2011.9.22,alex
				//
				var tag=typeof(QS_LPLRepId)!="undefined"&&QS_LPLRepId != '';
				self._getQSPortfolioList(callback);
				if (tag){
					self._getLPLPortfolioList(callback);
				}
                if(QSPC.checkPermission(0.08)&&QSPC.checkPermission(25)){
                    self._getScreenerList(callback);
                }
			});
		}
    },
    _getPortfolioListFromMap:function(){
        var wlist=[];
        for(var pId in this.watchListMap){
			if(this.watchListMap[pId].source == 'sector') continue; // remove the sector list.
            wlist.push({
                Name:this.watchListMap[pId].name,
                UpdateTime:this.watchListMap[pId].updateTime,
                Type:this.watchListMap[pId].type,
                TypeTxt:this.watchListMap[pId].typeTxt,
                PfId:pId,
                Owner:this.watchListMap[pId].owner,
				Source:this.watchListMap[pId].source,
                Permission:this.watchListMap[pId].permission
            });
        }
        return wlist.sort(function(a,b){
            var sortMap={"default":0,"LPLP":2,"LPLH":4,"QS":6,"screener":8,"temp":10};
            return sortMap[a.Source]>sortMap[b.Source]?1:-1;
        });
    },
    getHoldings: function(pId, callback){
		var self=this;
		var tempFun=function(){
			if (self.watchListMap[pId]) {
				self.watchListMap[pId].getHoldings(callback);
			}
			else {
				if (typeof(callback) == "function") {
					callback([]);
				}
			}
		};
		
		if (this.LPLStatus == self.STATUS_READY && this.QSStatus == self.STATUS_READY && this.bDefaultWatchlistLoaded){
			tempFun();
		}else{
			this.getPortfolioList(function(){tempFun();});
		}
    },
	moveHolding:function(pId,mHoldId,afterHoldId){
		if (this.watchListMap[pId]) {
            return this.watchListMap[pId].moveHolding(mHoldId,afterHoldId);
        }
	},
    insertHoldings:function(pId,holds,isTop){
        if (this.watchListMap[pId]) {
            return this.watchListMap[pId].insertHoldings(holds,isTop);
        }
    },
    updateHoldings:function(pId,holds){
        if (this.watchListMap[pId]) {
            this.watchListMap[pId].updateHoldings(holds);
        }
    },
    deleteHoldings:function(pId,holds){  // holds:[holdingId,hoildingId]
        if (this.watchListMap[pId]) {
            this.watchListMap[pId].deleteHoldings(holds);
        }
    },
    saveHoldings:function(pId,callback,autosave){  // save the holdings of watchlist.
        if (this.watchListMap[pId]) {
            this.watchListMap[pId].saveHoldings(callback,autosave);
        }
    },
    registerWatchlist:function(component,pId){
        if (!this.registeredMap[pId]) {
            this.registeredMap[pId] = [];
        }
        this.registeredMap[pId].push(component);
    },
    unregisterWatchlist:function(component,pId){
        if(this.registeredMap[pId]){
            for(var i=0;i<this.registeredMap[pId].length;i++){
                if(this.registeredMap[pId][i].id == component.id){
                    this.registeredMap[pId].splice(i,1);
					i--;
                }
            }
            /*if(this.registeredMap[pId].length<1){
                delete this.registeredMap[pId];
            }*/
        }
    },
    createHoldingMap:function(pId){
        if(this.watchListMap[pId]){
            this.watchListMap[pId].createHoldingMap();
        }
    },
    getHoldingMap:function(pId){
        if (this.watchListMap[pId]) {
            return this.watchListMap[pId].getHoldingMap();
        }
        return null;
    },
    getHoldingIdsByGkey:function(pId,gkey){
        if (this.watchListMap[pId]) {
            return this.watchListMap[pId].getHoldingIdsByGkey(gkey);
        }
        return null;
    },
	getHoldingByHoldId:function(pId,holdId){
        if (this.watchListMap[pId]) {
           return this.watchListMap[pId].getHoldingByHoldId(holdId);
        }
		return null;
    },
    getTypeById:function(pId){
        if (this.watchListMap[pId]) {
           return this.watchListMap[pId].type;
        }
        return null;
    },
    getNameById:function(pId){
        if (this.watchListMap[pId]) {
           return this.watchListMap[pId].name;
        }
        return null;
    },
	getSourceById:function(pId){
		if (this.watchListMap[pId]) {
           return this.watchListMap[pId].source;
        }
        return null;
    },
	getMaxTickers:function(id){//max tickers 
	    var maxCount=200;
	    if (!id) {
			if (QSPC.getConfig(0).isLPLUser || QSPC.getConfig(0).isDirectUser) {
				maxCount = 1000;
			}
		}else{
			//temp watchlist
			if(this.getSourceById(id)=='temp'){
				maxCount = 2000;
			}
		}
		return maxCount;
	},
	getPermissionById:function(pId){
        if(this.watchListMap[pId]){
			return this.watchListMap[pId].getPermission();
        }
        return 0;
    },
	setLPLGroupBy:function(pId,groupBy){
		if(this.watchListMap[pId]&&this.watchListMap[pId].source=='LPLP'){
            this.watchListMap[pId].LPLP_GroupBy=groupBy;
        }
	},
	getLPLGroupBy:function(pId){
        if(this.watchListMap[pId]&&this.watchListMap[pId].source=='LPLP'){
            return this.watchListMap[pId].LPLP_GroupBy;
        }
		return null;
    },
	clearLPLHoldings:function(pId){
		if(this.watchListMap[pId]&&this.watchListMap[pId].source=='LPLP'){
            this.watchListMap[pId].setReady(false);
        }
	},
	LPLGroup:function(pId,groupBy,callback){
        if(QSPC.getConfig(0).isLPLUser&&(groupBy=='Household'||groupBy=='AccountName')){
            var LPLP_GroupBy=this.getLPLGroupBy(pId);
            if(groupBy!=LPLP_GroupBy){
                this.setLPLGroupBy(pId,groupBy);
                this.clearLPLHoldings(pId);
            }	
        }
		if(typeof callback=='function') callback(groupBy);
    },
	saveAsWatchlist:function(name,pId,callback){
		if(this.watchListMap[pId]){
			var w = this.watchListMap[pId];
			var lengthHoldings=w.holdings.length,configLen=this.getMaxTickers(),len=0;
			len=Math.min(lengthHoldings,configLen);//save as the max tickers
			this.createWatchList(name,w.type,w.holdings.slice(0,len),function(data){
				if((!data.ret||data.ret!=-1)&&lengthHoldings>len){
					Util.alert(String.format(QS_Lang.text["watchlistsplitlimit"],configLen));
				}
				if(callback){
					callback(data);
				}
			});
		}
	},
	renameWatchlist:function(title,pId,type,callback){
		var self=this;
		//0 success
		DBHelper.renamePortfolio (title,pId,type,function(o){
			if (o != null) {
				var jData=$.evalJSON(o);
				if (jData.ret == '0') {
					if (self.watchListMap[pId]) {
						DBHelper.updateLocalPortfolio({PfId:pId,Name:title},jData.updateTime,'update');
						self.watchListMap[pId]._renameWatchlist(title, callback);
                        if (self.registeredMap[pId]) { // has component registered this wathlist.   
                            for (var i = 0; i < self.registeredMap[pId].length; i++) {
                                var com = self.registeredMap[pId][i];
                                if (com && typeof(com.onWatchlistRename) == "function") { // watchlist will unregister this pid.
                                    com.onWatchlistRename(pId,title);
                                }
                            }
                        }
						Util.message(QS_Lang.text["wsrenamesuccess"]);		
						return;
					}
				}
			}
			Util.message(QS_Lang.text["watchlistrenameerror"]);
			if(typeof callback=='function') callback();
		});
	},
	createTempWatchList:function(title,holdings,callback,tempID){
		var tempID=typeof tempID!='undefined'?tempID:new Date().getTime();
		this.watchListMap[tempID] = new watchlistData(tempID);
        this.watchListMap[tempID].name = title;
        this.watchListMap[tempID].type = 1;
        this.watchListMap[tempID].typeTxt = 'List';
        this.watchListMap[tempID].permission = 'Write';
        this.watchListMap[tempID].holdings = this.watchListMap[tempID]._sortHoldings(holdings);
        this.watchListMap[tempID].setReady(true);
		this.watchListMap[tempID].source = 'temp';
		if (typeof(callback) == "function") {
            callback({
                portfolioId: tempID,
                holdings: holdings
            });
        }
	},
    createWatchList:function(title,type,holdings,callback){
        var self=this;
		var holds = [];
		var len=holdings.length;
		for(var i=0;i<len;i++){
			var para = $.extend(true,{},holdings[i]);
			para.Action = "1";
			para.HoldingId = "";
			para.Rank = i*10+"";
			delete para.HldgId;
			delete para.gkey;
			delete para.NumOfShares;//delete NumOfShares
			delete para.PurchaseDate;//delete PurchaseDate
			delete para['P/L'];
			delete para.AccountName;
			delete para.Household;
			holds.push(para);
		}
        DBHelper.insertPortfolio(title, $.toJSON(holds), function(data){
            var holds = [], pid = -1, ret = -1;
            if (data != null) {
                var jData = $.evalJSON(data);
                if (jData) {
		            ret = jData.ret;
		            pid = jData.portId;
		            if ((pid != "" && isNaN(pid)) || (pid != "" && pid > 0)) {//isNaN?
		                self.watchListMap[pid] = new watchlistData(jData.portId);
		                self.watchListMap[pid].name = title;
		                self.watchListMap[pid].type = type;
		                self.watchListMap[pid].typeTxt = type == 0 ? 'Portfolio' : 'List';
		                self.watchListMap[pid].permission = 'Write';
		                if (jData.list && jData.list.Holdings) {
		                    self.watchListMap[pid].holdings = self.watchListMap[pid]._sortHoldings(jData.list.Holdings);
		                    self.watchListMap[pid].setReady(true);
		                }
		                holds = self.watchListMap[jData.portId].holdings;
		            }
		        }
            }
            if (typeof(callback) == "function") {
                callback({
                    portfolioId: pid,
                    holdings: holds,
                    ret: ret
                });
            }
        }, type);
    },
    _deleteScreenerWatchlist:function(id,callback){
        delete this.watchListMap[id]; 
        for(var wid in this.registeredMap){
            for (var i = 0; i < this.registeredMap[wid].length; i++) {
                var com = this.registeredMap[wid][i];
                if (com && typeof(com.onWatchlistDataDelete) == "function") { // watchlist will unregister this id.
                    com.onWatchlistDataDelete(id);
                }
            } 
        }
        if(this.registeredMap[id]&&this.registeredMap[id].length==0){
            delete this.registeredMap[id]; 
        }
        if (typeof(callback) == "function") {
            callback({
                portfolioId: id,
                op: true
            })
        }   
    },
    deleteWatchlist:function(pId,callback){
        if(this.getSourceById(pId)=="screener"){
            this._deleteScreenerWatchlist(pId,callback);
        }else{
            var self=this;
            DBHelper.deletePortfolio(pId,function(data){
                if(data!=null){
    				var jData=$.evalJSON(data);
    				if (jData.ret == 'true') {
    					delete self.watchListMap[pId]; // update the watchlist list.
    					if (self.registeredMap[pId]) { // has component registered this wathlist. 	
    						for (var i = 0; i < self.registeredMap[pId].length; i++) {
    							var com = self.registeredMap[pId][i];
    							if (com && typeof(com.onWatchlistDataDelete) == "function") { // watchlist will unregister this pid.
    								com.onWatchlistDataDelete(pId);
    								i--;
    							}
    						}
    						delete self.registeredMap[pId];	
    					}
    					DBHelper.updateLocalPortfolio({PfId:pId},jData.updateTime,'del');
    					if (typeof(callback) == "function") {
    						callback({
    							portfolioId: pId,
    							op: true
    						})
    					}	
    				}else{
    					if(typeof(callback)=="function"){
    	                    callback({portfolioId:pId,op:false})
    	                }
    				}
                }else{
    				if(typeof(callback)=="function"){
                        callback({portfolioId:pId,op:false})
                    }
    			}
            });
        }
    },
	formatNum:function(value){//#,###.00
	   if (QSPC.getConfig(0).isDotComUser) {
	   	   return value.replace(/,/g, "");
	   }else {
	   	   return value;
	   }
	   
	},
	getPortfolioSummary:function(pId,exsitHoldIds,callback){
		var self=this;
		if (self.watchListMap[pId].source == 'default') {
			callback(false, true);
		}else {
			var ps = self.watchListMap[pId].getPortfolioSummary(exsitHoldIds);
			if (ps.mixFlag) {
				callback(ps.mixFlag);
			}else {
				if (ps.holds.length == 0) {
					callback(ps.mixFlag, true);
				}
				else {
					//var type = QSPC.getConfig(0).isDotComUser ? 0 : 1;
					var type = 1;
					DBHelper.getPortfolioSummary(pId, $.toJSON(ps.holds), type, function(o){
						if(typeof o=='undefined'){
							o={};
						}
						callback(ps.mixFlag, false, o);
					});
				}
			}
		}
	}
};

var QS_watchlistDataManager = new watchlist_DataManager();

var watchlistData=function(id){
    this.cmd={
        ADD: '1',
        EDIT: '2',
        DEL: '3'
    };
    this.type=1;//0-portfolio,1-watchlist
    var qslang=QS_Lang.watchlist;
    this.typeTxt=qslang["type_list"];
    this.source='QS';//data source;eg:.com ,office..,LPLP,LPLH
    this.id=id;
    this.name=null;//portfolio/watchlist name
    this.updateTime=null;
    this.owner=qslang["dm_owner"];
    this.permission=qslang["dm_write"];
    this.holdings=[];
    this.ready=false;//if cache the data
    this.actionStack={};//operation stack {holdingid:{1:true,2:true,3:true}}
    this.holdingId=-1;
    this.holdingsMap = null;// {gkey:holdingIdList}
    this.PLdefCommission='0';
	//this.PLdefPrice=QSPC.getConfig(0).isDotComUser?'1':'0';
    //this.PLdefQuantity=QSPC.getConfig(0).isDotComUser?'1':'0';
	this.PLdefPrice='0';
	this.PLdefQuantity='0';
	this.LPLP_GroupBy='Household';
};
watchlistData.prototype={
	getPortfolioSummary:function(holdIds){
		var para=[],gkey,tickerType,exch,mixFlag=false;
		for(var i=0,l=this.holdings.length;i<l;i++){
			if(!this.holdings[i].Invalid&&$.inArray(this.holdings[i].HldgId+'',holdIds)>-1){//get all visable rows to sum
				gkey=this.holdings[i].gkey;
				if(!gkey||gkey==''||gkey==null){
					continue;
				}
				if(exch&&gkey.split(":")[0]!=exch){//different currency 
				    mixFlag=true;
					break;
				}
				exch=gkey.split(":")[0];
				tickerType=gData[gkey]&&gData[gkey].type?gData[gkey].type:'';
				para.push({
                    pk:exch+":"+tickerType+":"+gkey.split(":")[1],
					ns:this.holdings[i].NumOfShares,
					//pp:QSPC.getConfig(0).isDotComUser?this.holdings[i].CostBasis:this.holdings[i].PurchasePrice,
					pp:this.holdings[i].PurchasePrice,
					cm:this.holdings[i].Comm
                });
			}	
		}
		return {
			holds: para,
			mixFlag: mixFlag
		};
	},
	getPermission:function(){
        if(this.source=='screener'||this.source=='default'||this.source=='temp'||this.source=='LPLP'||this.source=='LPLH'||(QSPC.getConfig(0).isDotComUser&&this.type==0)){
			return 0;
        }else{
            return 1;
        }
	},
    getHoldings:function(callback){
        var self=this;
		if (this.ready && typeof(callback) == "function") {
			callback(self.holdings,self.id);
		}else {
			if (this.source == 'default') {//default watchlist
				this._getDefaultHoldings(callback);
//				this.holdingsMap = null;// clear the holdings map.
//				if (typeof(callback) == "function") {
//					callback(self.holdings);
//				}
			}else if (this.source == 'QS') {					
				DBHelper.getPortfolio(this.id, function(data){
					this.holdingsMap = null;// clear the holdings map.
					if (data != null && data != '') {
						var jData = $.evalJSON(data);
						self.holdings = self._sortHoldings(jData.Holdings);
						self.setReady(true);
						self.actionStack = {};
						self.holdingId = -1;
					}
					if (typeof(callback) == "function") {
						callback(self.holdings,self.id);
					}
				});
			}else if (this.source == 'LPLP') {						
                DBHelper.getLPLPracticeHoldings(this.id,this.LPLP_GroupBy, function(data){
					this.holdingsMap = null;// clear the holdings map.
					if (data != null && data != '') {
						var jData = $.evalJSON(data);
						self._setLPLHoldings(jData.Holdings, function(){
							self.setReady(true);
							self.actionStack = {};
							self.holdingId = -1;
							if (typeof(callback) == "function") {
								callback(self.holdings,self.id);
							}
						});
					}
				});
			}else if(this.source == 'LPLH') {
				DBHelper.getLPLHouseholdHoldings(this.id, function(data){
					this.holdingsMap = null;// clear the holdings map.
					if (data != null && data != '') {
						var jData = $.evalJSON(data);
						self._setLPLHoldings(jData.Holdings, function(){
							self.setReady(true);
							self.actionStack = {};
							self.holdingId = -1;
							if (typeof(callback) == "function") {
								callback(self.holdings,self.id);
							}
						});
					}
				});						
			}else if(this.source == "sector"){  // get the stock list in one sector.
                this._getSectorHoldings(callback);
                this.holdingsMap = null;// clear the holdings map.
            }else if(this.source == "screener"){  // get the stock list in one sector.
                this.holdingsMap = null;// clear the holdings map.
                this._getScreenerHoldings(callback);
            }
		}     
    },
	
    _getDefaultHoldings:function(callback){
		var self=this;

		DBHelper.getDefaultTickersByWatchId(this.id,function(data){

			if(data&&data!="error"){
				var jTickerData = $.evalJSON(data);
				if(jTickerData&&jTickerData.tickers){
				
					var theWatchlist=QS_watchlistDataManager.watchListMap[self.id];
					if (theWatchlist) {
						
						if (theWatchlist.securityType) {
							var group = theWatchlist.group;
							DBHelper.getCommodity(group,function(data){
								if (data != null && data != '') {
									self.holdings = [];
									var jData = $.evalJSON(data);
									var symbols=jData.Overview;
									var tickers=jTickerData.tickers;
									var s;
									var d = QS_watchlistDataManager.formatHoldingDate(new Date());
									for(var j=0,len=tickers.length;j<len;j++){
										s=symbols[tickers[j]];
										if(s){
											var details=s.Details;
											var feedSrcId=s.FeedSrcId;
											var exch=s.Exch||'';
											var name=s.Name||'';
											var idx=name.indexOf('Cont.');
											if(idx>-1){
												name=name.substring(0,idx);
											}   
											if(!details||!feedSrcId){
												continue;
											}
											if(typeof QS_FuturesMap=='undefined'){
												QS_FuturesMap={};
											}
											QS_FuturesMap[tickers[j]]=[name,exch];
											var symbol;
											for(var i=0,l=details.length;i<l;i++){
												symbol=details[i][0];
												if(symbol.substring(symbol.length-1,symbol.length)!='Y'){
													self.holdings.push({
														HldgId: self.holdingId--,
														SecId: "/"+feedSrcId+":"+symbol,
														Rank: i + 1,
														Quantity: self.PLdefQuantity,
														NumOfShares: self.PLdefCommission,
														PurchasePrice: self.PLdefPrice,
														Comm: self.PLdefCommission,
														Ticker: '',
														Date: d,
														PurchaseDate: d
													});
													break;
												}
											}
										}
									}
									self.setReady(true);
									self.holdingsMap = null;// clear the holdings map.
									if (typeof(callback) == "function") {
										callback(self.holdings,self.id);
									}
								}
							});
						}else{
							self.holdingId = -1; // set to default.
							var tickers = jTickerData.tickers;
							self.holdings = [];
							var d = QS_watchlistDataManager.formatHoldingDate(new Date());
							for (var i = 0, l = tickers.length; i < l; i++) {
								self.holdings.push({
									HldgId: self.holdingId--,
									SecId: tickers[i],
									Rank: i + 1,
									Quantity: self.PLdefQuantity,
									NumOfShares: self.PLdefCommission,
									PurchasePrice: self.PLdefPrice,
									Comm: self.PLdefCommission,
									Ticker: '',
									Date: d,
									PurchaseDate: d
								});
							}
							self.setReady(true);
							self.holdingsMap = null;// clear the holdings map.
							if (typeof(callback) == "function") {
								callback(self.holdings,self.id);
							}
						}
					}
												
				}
			}
		});

    },
	_getSectorHoldings:function(callback){ // get sectors holdings
        var code = "LT735", value = this.industryId,a ="";
        if(this.sectorType=="sp"){
            code = "STA4H", value = this.industryId;
        }
        if(typeof(this.region)!="undefined"){
            a = ',{"Name":"OS01V","Type":3,"IsInclude":true,"TextOperator":2,"Value":"'+this.region+'"}';
        }
        var query = '{"Keywords":[{"Name":"'+code+'","Type":1,"TextOperator":1,"Value":"'+value+'"},{"Name":"OS010","Type":3,"IsInclude":true,"TextOperator":1,"Value":"ST"}'+a+'],"SecType":"ST"}'
        var data = {col:'{Columns:["OS06Y"]}',count:2000,operator:"AND",type:'ticker',start:0,query:query};
        var self=this;
        var d = QS_watchlistDataManager.formatHoldingDate(new Date());
        $.post(DBHelper.sectorUrl, data, function(returnData){
            var returnData=returnData.replace(/rn/g, "");
            if($.trim(returnData)=='') return;
            var jD = $.evalJSON(returnData);
            var cols = jD.Columns;
            self.holdingId=-1;
            self.holdings = [];
            for(var i=0;i<cols.length;i++){
                self.holdings.push({
                    HldgId: self.holdingId--,
                    SecId: cols[i]["OS06Y"],
                    Rank: i + 1,
                    Quantity:self.PLdefQuantity,
                    NumOfShares:self.PLdefCommission,
                    PurchasePrice:self.PLdefPrice,
                    Comm:self.PLdefCommission,
                    Ticker: '',
                    Date:d,
                    PurchaseDate:d
                });
                
            }
            self.setReady(true);
            if (typeof(callback) == "function") {
                callback(self.holdings);
            }
        });
    },
    _getScreenerHoldings:function(callback){//get the latest
        var self=this;
        QS_watchlistDataManager.screenerSaved.getSearchData(this.id,function(data){
            if (data != null) {
                var date = QS_watchlistDataManager.formatHoldingDate(new Date());
                var max=QS_watchlistDataManager.getMaxTickers(self.id);
                QS_BaseSearch.getPidBySavedData(data,
                    max,
                    [QS_BaseSearch.PIdCode,QS_BaseSearch.SIdCode,QS_BaseSearch.tickerCode,QS_BaseSearch.keyWordCode],
                    data.sortfield,data.sorttype,function(d){
                        if(!self.ready){
                            self.setReady(true);
                            self.holdings = [];
                            var sid=QS_BaseSearch.SIdCode,temp=null;
                            if(d["Count"]>max){
                                Util.alert(String.format(QS_Lang.text["watchlistlimit"], max));
                            }
                            for (var i = 0, l = d["Rows"]; i < l; i++) {
                                temp = d["Columns"][i];
                                self.holdings.push({
                                    HldgId: self.holdingId--,
                                    SecId: temp[sid],
                                    Rank: i + 1,
                                    Quantity:self.PLdefQuantity,
                                    NumOfShares:self.PLdefCommission,
                                    PurchasePrice:self.PLdefPrice,
                                    Comm:self.PLdefCommission,
                                    Ticker: '',
                                    Date:date,
                                    PurchaseDate:date
                                });
                            }
                        }
                        if (typeof(callback) == "function") {
                            callback(self.holdings,self.id);
                        }
                    });
            }else{
                if (typeof(callback) == "function") {
                    callback(self.holdings,self.id);
                }
            }
        });
    },
    getHoldingMap:function(){
        return this.holdingsMap;
    },
    getHoldingIdsByGkey:function(gkey){
        if(this.holdingsMap!=null){
            return this.holdingsMap[gkey];
        }
        return null;
    },
	getHoldingByHoldId:function(holdId){
		var ret=null;
		if(this.holdings!=null){
			for(var i=0,l=this.holdings.length;i<l;i++){
                if(this.holdings[i].HldgId==holdId){
                    ret = this.holdings[i];
					break;
                }
            }
		}
		return ret;
	},
    createHoldingMap:function(){
        //if(this.holdingsMap==null){// there is no holding map in watchlist
            this.holdingsMap = {};
            var len = this.holdings.length;
            var sId,gkey;
            for(var i=0;i<len;i++){
                sId = this.holdings[i].SecId;
                gkey = gIdMap[sId];
                if(gkey){
                    if(!this.holdingsMap[gkey]){
                        this.holdingsMap[gkey] = [];
                    }
                    this.holdingsMap[gkey].push(this.holdings[i].HldgId);
                    this.holdings[i].gkey = gkey;
                }               
            }
        //}
    },
    saveHoldings:function(callback,autosave){
        var opList=[],self=this;
        for(var holdId in this.actionStack){
            if(this.actionStack[holdId]){
                for(var act in this.actionStack[holdId]){
                    var para=this._getParaList(holdId,act,this.actionStack[holdId][act]);
                    if(this.actionStack[holdId][act]&&para){
                        opList.push(para);
                    }
                }
            }
        }
        if(this.source=='QS'){  // 
            if(opList.length<1) {
				if(typeof(callback)=="function"){   // not holdings need to save.
					callback([]);
				}
			}else{
				this.actionStack={};//clear operation stack
	            DBHelper.updatePortfolio(this.id,$.toJSON(opList),function(data){
	                 if(data!=null&&data!=''){
	                     var jData=$.evalJSON(data);
	                     if (jData.ret=="0"&&jData.list != null) {  // update success.
	                        self.holdings = self._sortHoldings(jData.list.Holdings);
	                        self.holdingsMap = null;
	                        self.createHoldingMap();  // recrate the holdings map.
                            if(!autosave){
    	                        self._refreshWatchlists(callback);  // notify the watchlist to update the holdings.
                            }
	                        //self._refreshHoldings(data.list.Holdings,callback);
	                     }
	                 }      
	            });
			}
        }else if(this.source=="screener"){//screener need update watchlist
            this.getHoldings(function(){
                if(!autosave){
                    self._refreshWatchlists(callback);  // notify the watchlist to update the holdings.
                }
            });
        }
    },
	
    _refreshWatchlists:function(callback){
        if(QS_watchlistDataManager.registeredMap[this.id]){  // has component registered this wathlist. 
            if(typeof(callback)== "function"){
                callback(this.id,this.holdings);
            }
            for(var i=0;i< QS_watchlistDataManager.registeredMap[this.id].length;i++){
                var com = QS_watchlistDataManager.registeredMap[this.id][i];
                if(com&& typeof(com.refreshHoldings)=="function"){
                    com.refreshHoldings(this.id,this.holdings);
                }
                
            }
        }
    },
    _refreshHoldings:function(data,callback){
        if(data!=null&&data.length!=0){
            var notifyHoldings={};
            for(var i=0,l=data.length;i<l;i++){
                for(var j=0,len=this.holdings.length;j<len;j++){
                    if(data[i].oldHoldingId<0&&data[i].oldHoldingId==this.holdings[i].HldgId){  // has new holding id.
                        this.holdings[i].HldgId=data[i].HldgId;
                        notifyHoldings[data[i].oldHoldingId]=data[i].HldgId;
                        var gkey = this.holdings[i].gkey;
                        if(gkey&&this.holdingsMap[gkey]){  // update holding id in the holdings map;
                            for(var h=0;i<this.holdingsMap[gkey].length;h++){
                                if(this.holdingsMap[gkey][h]==data[i].oldHoldingId){
                                    this.holdingsMap[gkey][h] = data[i].HldgId;
                                }
                            }
                        }
                    }
                }
                if(this.actionStack[data[i].oldHoldingId]){//refresh actionStack holdid
                    this.actionStack[data[i].HldgId]=this.actionStack[data[i].oldHoldingId];
                    delete this.actionStack[data[i].oldHoldingId];
                }
            }
            if(QS_watchlistDataManager.registeredMap[this.id]){  // has component registered this wathlist. 
                for(var i=0;i< QS_watchlistDataManager.registeredMap[this.id].length;i++){
                    var com = QS_watchlistDataManager.registeredMap[this.id][i];
                    if(com&& typeof(com.refreshHoldingsId)=="function"){
                        com.refreshHoldingsId(notifyHoldings);
                    }
                    
                }
            }
            if(typeof(callback)== "function"){
                callback(notifyHoldings);
            }   
        }
    },
	moveHolding:function(mHoldId,afterHoldId){
		var m=0,a=0,flag=2;
		for(var i=0;i<this.holdings.length;i++){
			if(this.holdings[i].HldgId==mHoldId){
				m=i,flag--;
			}
			if(this.holdings[i].HldgId == afterHoldId){
				a = i;flag--;
			}
			if(flag==0) break;
		}
		var low = null,high=this.holdings[a].Rank;
		if (a > 0) {
			low = this.holdings[a-1].Rank;
		}
		var newRank = this.rankGenerater(low,high);
		var moveD = this.holdings[m];
		if(!this.actionStack[mHoldId])this.actionStack[mHoldId] = {};  // remember the update operate.
        if (!this.actionStack[mHoldId][this.cmd.ADD]){
            this.actionStack[mHoldId][this.cmd.EDIT] = true;
        }
		moveD.Rank = newRank;
		this.holdings.splice(m,1);
		if(m<a)a--;
		this.holdings.splice(a,0,moveD); // insert the move holdings.
	},
    insertHoldings:function(holdings,isTop){
        var holdId,gkey,holdIds=[];
        var startRank = this.holdings.length<1?1:parseInt(this.holdings[0].Rank)-1;
        var endRank = this.holdings.length<1?1:parseInt(this.holdings[this.holdings.length-1].Rank)+1;
        for(var i=0,l=holdings.length;i<l;i++){
			gkey = holdings[i].gkey;
            holdId=this.holdingId--;
            holdings[i]['HldgId']=holdId;
			holdings[i].Quantity=typeof holdings[i].Quantity!='undefined'?holdings[i].Quantity:this.PLdefQuantity;
            holdings[i].PurchasePrice=typeof holdings[i].PurchasePrice!='undefined'?holdings[i].PurchasePrice:this.PLdefPrice;
//            if(QSPC.getConfig(0).isDotComUser){//dotcom user set Quantity >=1,PurchasePrice>=1
//                holdings[i].Quantity = holdings[i].Quantity < 1 ? '1' : holdings[i].Quantity;
//                holdings[i].PurchasePrice = holdings[i].PurchasePrice < 1 ? '1' : holdings[i].PurchasePrice;
//            }
            holdings[i].NumOfShares=holdings[i].Quantity;//set the quantity to NumOfShares
            holdings[i].Comm=typeof holdings[i].Comm!='undefined'?holdings[i].Comm:this.PLdefCommission;
			holdings[i].Ticker=typeof holdings[i].Ticker!='undefined'?holdings[i].Ticker:this._getHoldingTicker(gkey);
			holdings[i].Date=typeof holdings[i].Date!='undefined'?holdings[i].Date:QS_watchlistDataManager.formatHoldingDate(new Date());
			holdings[i].PurchaseDate=holdings[i].Date;
            if(typeof(isTop)=="undefined"||isTop){
                holdings[i].Rank = startRank;
                this.holdings.unshift(holdings[i]);
                startRank --;
            }else{
                holdings[i].Rank = endRank;
                this.holdings.push(holdings[i]);
                endRank++;
            }
            if(!this.actionStack[holdId]){
                this.actionStack[holdId]={};
            } 
            if(gkey){                            // update the holdings map.
                if(this.holdingsMap==null){
					this.holdingsMap = {};
				}
                if(!this.holdingsMap[gkey]){
                    this.holdingsMap[gkey] = [];
                }
                this.holdingsMap[gkey].push(holdId);
            }
            holdIds.push(holdId);
            this.actionStack[holdId][this.cmd.ADD]=true;
        }
        return holdIds;
    },
    updateHoldings:function(holdings){
        for(var i=0,l=holdings.length;i<l;i++){
            for(var j=0,len=this.holdings.length;j<len;j++){
                if(this.holdings[j].HldgId==holdings[i].HldgId){  
					if(holdings[i].Quantity){//set the quantity to NumOfShares
                        holdings[i].NumOfShares=holdings[i].Quantity;
					}
					$.extend(this.holdings[j],holdings[i]);
					if(!this.actionStack[holdings[i].HldgId])this.actionStack[holdings[i].HldgId] = {};
                    if (!this.actionStack[holdings[i].HldgId][this.cmd.ADD]){
                        this.actionStack[holdings[i].HldgId][this.cmd.EDIT] = true;
                    }
                    break;
                }
            }           
        }
    },
	rankGenerater:function(low,high){  // generate new rank for an inserted holding.
		if(low==null)return (high-10);
		if(high==null)return (low+10);
		else return (low+high)/2;
	},
    deleteHoldings:function(holdIds){
        for(var i=0,l=holdIds.length;i<l;i++){
            for(var j=0,len=this.holdings.length;j<len;j++){
                if(this.holdings[j].HldgId==holdIds[i]){
                   var gkey = this.holdings[j].gkey;    
                   if(gkey&&this.holdingsMap[gkey]){   // delete the holding Id from the holdings map.
                       for(var h=0;h<this.holdingsMap[gkey].length;h++){
                           if(this.holdingsMap[gkey][h]==holdIds[i]){
                              this.holdingsMap[gkey].splice(h,1);
							  h--;
                              if(this.holdingsMap[gkey].length ==0){
                                delete this.holdingsMap[gkey];
								break;
                              }
                           }
                       }
                   }
                   if(holdIds[i]<0){  // this holding has not saved to DB
                        delete this.actionStack[holdIds[i]];       
                   }else{
				   	    if(!this.actionStack[holdIds[i]]){
							this.actionStack[holdIds[i]]={};
						}
                        this.actionStack[holdIds[i]][this.cmd.DEL]=$.extend(true,{},this.holdings[j]);
                        delete this.actionStack[holdIds[i]][this.cmd.ADD];
                        delete this.actionStack[holdIds[i]][this.cmd.EDIT];
                   } 
				   this.holdings.splice(j,1);
                   break;
                }
            }           
        }
    },
	_getHoldingTicker:function(gkey){
		if(typeof gkey=='undefined'||gkey==''){
			return '';
		}
		if(QSPC.getConfig(0).isDotComUser){
			return gData[gkey]&&gData[gkey].Name?gData[gkey].Name:"";
		}else{
			return gData[gkey]&&gData[gkey].Ticker?gData[gkey].Ticker:"";
		}
	},
    _getParaList:function(holdId,act,hold){
        var para;
		var now = new Date(),
            year = now.getFullYear(),
            month = now.getMonth() + 1
            month = month < 10 ? ('0' + month) : month,
            day = now.getDate(),
            day = day < 10 ? ('0' + day) : day,
            date = month + '-' + day + '-' + year;
        if(act==3){ // delete holdings
            para =  hold;
			para.HoldingId = para.HldgId.toString();
			para.Ticker = para.Ticker?para.Ticker:this._getHoldingTicker(para.gkey);
			if(para.Invalid){//set Ticker as an invalid flag
				para.Ticker+="||Invalid";
			}			
			para.Date = para.Date?para.Date:date;
			delete para.HldgId;
            delete para.gkey;
			delete para.NumOfShares;//delete NumOfShares
			delete para.PurchaseDate;//delete PurchaseDate
            delete para['P/L'];
			delete para.AccountName;
            delete para.Household;
			delete para.Invalid;
			para.Action = "3";
        }else{
			for(var i=0,l=this.holdings.length;i<l;i++){
	            if(this.holdings[i].HldgId==holdId){
	                para={};
	                $.extend(true,para,this.holdings[i]);
					para.Ticker = para.Ticker?para.Ticker:this._getHoldingTicker(para.gkey);//set Name
	                if(para.Invalid){
		                para.Ticker+="||Invalid";
		            }   
					para.HoldingId = para.HldgId.toString();   // change the parameter name.
	                para.Rank = para.Rank.toString();   // change the parameter name.
					para.Date = para.Date?para.Date:date;
	                if (act == 1) {
						para.HoldingId = "";
					}
	                delete para.HldgId;
	                delete para.gkey;
					delete para.NumOfShares;//delete NumOfShares
					delete para.PurchaseDate;//delete PurchaseDate
					delete para['P/L'];
					delete para.AccountName;
					delete para.Household;
					delete para.Invalid;
	                para['Action']=act;
	                break;
	            }
	        }
		}		
        return para;
    },
    setReady:function(bool){
        this.ready=bool;
        if(!bool){
            this.holdings = [];
        }
    },
    _sortHoldings:function(data){
        if(data==null||data.length==0){
            return [];
        }
        var temp,t;
        for(var i=0;i<data.length;i++){			
            if(data[i].SecId==""){
                data.splice(i,1)
                i--;
                continue;
            }
			data[i].Quantity=typeof data[i].Quantity!='undefined'?QS_watchlistDataManager.formatNum(data[i].Quantity):this.PLdefQuantity;
			data[i].Rank=typeof data[i].Rank!='undefined'?parseFloat(data[i].Rank):i*10;
            data[i].PurchasePrice=typeof data[i].PurchasePrice!='undefined'?QS_watchlistDataManager.formatNum(data[i].PurchasePrice):this.PLdefPrice;
//			if(QSPC.getConfig(0).isDotComUser){//dotcom user set Quantity >=1,PurchasePrice>=1
//                data[i].Quantity = data[i].Quantity < 1 ? '1' : data[i].Quantity;
//                data[i].PurchasePrice = data[i].PurchasePrice < 1 ? '1' : data[i].PurchasePrice;
//				data[i].CostBasis = typeof data[i].CostBasis!='undefined'?QS_watchlistDataManager.formatNum(data[i].CostBasis):this.PLdefPrice;
//            }
			data[i].NumOfShares=data[i].Quantity;
            data[i].PurchaseDate=data[i].Date;
			data[i].Comm=typeof data[i].Comm!='undefined'?QS_watchlistDataManager.formatNum(data[i].Comm):this.PLdefCommission;
			if(typeof data[i].Ticker!='undefined'){
				t=data[i].Ticker.split("||");
				if(t[1]=='Invalid'){
					data[i].Ticker=t[0];
					data[i].Invalid=true;
				}
			}
            if(i==0)continue;
            for(var j=i;j>0;j--){
                if(data[j].Rank<data[j-1].Rank){
                    temp=data[j];
                    data[j]=data[j-1];
                    data[j-1]=temp;
                }
            }
        }
        /*data.sort(function(a,b){
            return a.rank>b.rank;
        });*/
        return data;
    },
	_getHouseholdName:function(name){
		if(this.source=='LPLP'){
			return name;
			//return QS_watchlistDataManager.getNameById(pId)==null?'':QS_watchlistDataManager.getNameById(pId);
		}else if(this.source=='LPLH'){
			return this.name;
		}
	},
	_renameWatchlist:function(newname,callback){
		this.name=newname;
		if (typeof QS_watchlistDataManager.registeredMap[this.id] != 'undefined') {
			for (var i = 0, l = QS_watchlistDataManager.registeredMap[this.id].length; i < l; i++) {
				var obj = QS_watchlistDataManager.registeredMap[this.id][i];
				if (typeof obj._renameTab == 'function') {
					obj._renameTab(this.id, this.name);
				}
			}
		}
		QS_WatchlistStartUpManager.sync();
		if(typeof callback=='function'){			
				callback();
		}
	},
	_setLPLHoldings:function(data,callback){
		var now = new Date(),
            year = now.getFullYear(),
            month = now.getMonth() + 1
            month = month < 10 ? ('0' + month) : month,
            day = now.getDate(),
            day = day < 10 ? ('0' + day) : day,
            date = month + '-' + day + '-' + year;
		var self=this;
		var tickers=[],secIdMap={};
		for(var i=0,l=data.length;i<l;i++){
			if(!secIdMap[data[i].SecId]){//splice the reduplicate secID
			    tickers.push(data[i].SecId);	
			    secIdMap[data[i].SecId]=true;
			}
			data[i].tempId=data[i].SecId;        
        }
		if(QS_watchlistDataManager.LPLTickerValidation){
			QS_watchlistDataManager.LPLTickerValidation.showAlert=false;
			QS_watchlistDataManager.LPLTickerValidation.checkTickers(tickers,function(gkeyList){
				if(gkeyList&gkeyList.length==0){
					return;
				}
				self.holdings=[];
				for(var j=0,len=data.length;j<len;j++){
					for (var i = 0, l = gkeyList.length; i < l; i++) {
						var gkey = gkeyList[i];
						if (gData[gkey].CUSIP && data[j].tempId == gData[gkey].CUSIP && data[j].Type == 'CUP') {
							self.holdings.push({
								HldgId: self.holdingId--,
								Rank: j + 1,
								SecId: gData[gkey].performanceId ? gData[gkey].performanceId : gData[gkey].secId ? gData[gkey].secId : '',
								PurchasePrice: data[j].PurchasePrice == '' ? self.PLdefPrice : data[j].PurchasePrice,
								Quantity: data[j].Quantity == '' ? self.PLdefQuantity : data[j].Quantity,
								NumOfShares: data[j].Quantity == '' ? self.PLdefQuantity : data[j].Quantity,
								Date: data[j].Date == '' ? date : data[j].Date,
                                PurchaseDate: data[j].Date == '' ? date : data[j].Date,
								Comm: self.PLdefCommission,
								AccountName: data[j].AccountName,
								//Name:data[j].Name==''?'':data[j].Name,
								Ticker: self._getHoldingTicker(gkey),
								Household: self._getHouseholdName(data[j].PfName)
							});
							break;
						}
						else if (gData[gkey].ticker && data[j].tempId == gData[gkey].ticker && data[j].Type == 'SYM') {
							self.holdings.push({
								HldgId: self.holdingId--,
								Rank: j + 1,
								SecId: gData[gkey].performanceId ? gData[gkey].performanceId : gData[gkey].secId ? gData[gkey].secId : '',
								PurchasePrice: data[j].PurchasePrice == '' ? self.PLdefPrice : data[j].PurchasePrice,
								Quantity: data[j].Quantity == '' ? self.PLdefQuantity : data[j].Quantity,
								NumOfShares: data[j].Quantity == '' ? self.PLdefQuantity : data[j].Quantity,
								Date: data[j].Date == '' ? date : data[j].Date,
                                PurchaseDate: data[j].Date == '' ? date : data[j].Date,
								Comm: self.PLdefCommission,
								AccountName: data[j].AccountName,
								Ticker: self._getHoldingTicker(gkey),
								Household: self._getHouseholdName(data[j].PfName)
							});
							break;
						}else if (gData[gkey].secId && data[j].tempId == gData[gkey].secId && data[j].Type == 'IDX') {
							self.holdings.push({
								HldgId: self.holdingId--,
								Rank: j + 1,
								SecId: gData[gkey].performanceId ? gData[gkey].performanceId : gData[gkey].secId ? gData[gkey].secId : '',
								PurchasePrice: data[j].PurchasePrice == '' ? self.PLdefPrice : data[j].PurchasePrice,
								Quantity: data[j].Quantity == '' ? self.PLdefQuantity : data[j].Quantity,
								NumOfShares: data[j].Quantity == '' ? self.PLdefQuantity : data[j].Quantity,
								Date: data[j].Date == '' ? date : data[j].Date,
                                PurchaseDate: data[j].Date == '' ? date : data[j].Date,
								Comm: self.PLdefCommission,
								AccountName: data[j].AccountName,
								Ticker: self._getHoldingTicker(gkey),
								Household: self._getHouseholdName(data[j].PfName)
							});
							break;
						}
					}
				}
				if (typeof callback == "function") {
                    callback();
                }
			});
		}
	}
};

